package com.hly.tool.route;


import com.hly.tool.constants.Constants;
import com.hly.tool.constants.HConstants;
import com.hly.tool.object.HDomainObject;
import com.matrixone.apps.common.Route;
import com.matrixone.apps.domain.DomainConstants;
import com.matrixone.apps.domain.DomainObject;
import com.matrixone.apps.domain.DomainRelationship;
import com.matrixone.apps.domain.util.*;
import com.matrixone.apps.framework.ui.UIUtil;
import com.matrixone.apps.program.ProgramCentralConstants;
import matrix.db.BusinessObject;
import matrix.db.Context;
import matrix.db.JPO;
import matrix.util.MatrixException;
import matrix.util.StringList;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.*;
import java.util.logging.Logger;

/**
 * @Auther: Jack.Hao
 * @Date: 2021/4/9 11:37
 * @Description:
 */
public class RouteUtil {

    private static final Logger _logger = Logger.getLogger("RouteUtil");
    //流程模板
    private static final String TYPE_ROUTE_TEMPLATE = "Route Template";
    private static final String POLICY_ROUTE_TEMPLATE = "Route Template";
    private static final String RELATIONSHIP_ROUTE_TEMPLATES = "Route Templates";
    private static final String RELATIONSHIP_ROUTENODE = "Route Node";
    private static final String ATTRIBUTE_ESERVICE_NEXT_NUMBER = "eService Next Number";


    /**
     * 通过流程的属性检查
     * 对象关联的流程 已经结束流程
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static boolean checkObjectFinishRoute(Context context, String objectId) throws Exception {
        DomainObject domainObject = DomainObject.newInstance(context, objectId);
        return checkObjectFinishRoute(context, domainObject);
    }

    /**
     * 通过流程的属性检查 对象关联的流程
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static boolean checkObjectRoute(Context context, String objectId, String attr, String attrValue) throws Exception {
        DomainObject domainObject = DomainObject.newInstance(context, objectId);
        return checkObjectRoute(context, domainObject, attr, attrValue);
    }


    /**
     * 通过流程的属性检查
     * 对象关联的流程 已经结束流程
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static boolean checkObjectFinishRoute(Context context, DomainObject domainObject) throws Exception {
        StringList busList = new StringList();
        StringList relList = new StringList();
        busList.add(DomainConstants.SELECT_ID);
        busList.add("attribute[Route Status]");
//        MapList relatedRoutes = domainObject.getRelatedObjects(context, Constants.rel_ObjectRoute, Constants.type_Route, busList, relList, false, true, (short) 1, null, null,0);
        MapList relatedRoutes = HDomainObject.getRelatedObjectsAttr(context, domainObject, Constants.type_Route, Constants.rel_ObjectRoute, busList, relList, false, true, (short) 1);

        boolean flag = true;
        for (int i = 0; i < relatedRoutes.size(); i++) {
            Map map_i = (Map) relatedRoutes.get(i);
            String id_i = (String) map_i.get("id");
            String RouteStatus_i = (String) map_i.get("attribute[Route Status]");
            DomainObject domainObject_i = DomainObject.newInstance(context, id_i);
            //Complete
            String state = domainObject_i.getCurrentState(context).getName();
            if (!(state.equals("Complete") || RouteStatus_i.equals("Finished"))) {
                flag = false;
                break;
            }
        }

        return flag;
    }

    /**
     * 通过流程的属性检查 对象关联的流程
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static boolean checkObjectRoute(Context context, DomainObject domainObject, String attr, String attrValue) throws Exception {
        StringList busList = new StringList();
        StringList relList = new StringList();
        busList.add(DomainConstants.SELECT_ID);
        busList.add("attribute[" + attr + "]");
//        MapList relatedRoutes = domainObject.getRelatedObjects(context, Constants.rel_ObjectRoute, Constants.type_Route, busList, relList, false, true, (short) 1, null, null);
        MapList relatedRoutes = HDomainObject.getRelatedObjectsAttr(context, domainObject, Constants.type_Route, Constants.rel_ObjectRoute, busList, relList, false, true, (short) 1);
        for (int i = 0; i < relatedRoutes.size(); i++) {
            Map map_i = (Map) relatedRoutes.get(i);
//            String id_i = (String) map_i.get("id");
//            DomainObject domainObject_i = DomainObject.newInstance(context, id_i);
//            String attributeValue = domainObject_i.getAttributeValue(context, attr);
            String attrVal_i = (String) map_i.get("attribute[" + attr + "]");
            if (UIUtil.isNotNullAndNotEmpty(attrVal_i) && attrVal_i.equals(attrValue)) {
                return false;
            }
        }

        return true;
    }

    /**
     * create empty route
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static Map createEmptyRoute(Context context) throws Exception {
        //    System.out.println("templateId = " + templateId);
        Map paramMap = new HashMap<String, Object>();
        String language = context.getLocale().getLanguage();

        paramMap.put("RouteCompletionAction", "Promote Connected Object");
//    paramMap.put("RouteCompletionAction", "Notify Route Owner");
        paramMap.put("Description", "");
        paramMap.put("languageStr", language);
        paramMap.put("portalMode", DomainConstants.EMPTY_STRING);
        paramMap.put("RouteBasePurpose", "Approval");
        paramMap.put("supplierOrgId", DomainConstants.EMPTY_STRING);
        paramMap.put("suiteKey", "Framework");
        paramMap.put("TemplateOID", null);
        paramMap.put("TemplateDisplay", DomainConstants.EMPTY_STRING);
        paramMap.put("VisbleToParent", DomainConstants.EMPTY_STRING);
        paramMap.put("AutoStopOnRejection", "Immediate");

        paramMap.put("Name", DomainConstants.EMPTY_STRING);
        paramMap.put("autoNameCheck", "true");
        paramMap.put("AutoNameSeries", DomainConstants.EMPTY_STRING);
        paramMap.put("Vault", DomainConstants.EMPTY_STRING);
        paramMap.put("Revision", DomainConstants.EMPTY_STRING);
        paramMap.put("selscope", "Organization");
        paramMap.put("folderId", DomainConstants.EMPTY_STRING);
        paramMap.put("txtWSFolder", "\u9009\u62e9\u4f5c\u7528\u8303\u56f4");

//        System.out.println("paramMap = " + paramMap);

        String[] args = JPO.packArgs(paramMap);
        Map routeMap = (Map) JPO.invoke(context, "emxRoute", null, "createRouteProcess", args, Map.class);
//        System.out.println("routeMap = " + routeMap);
        return routeMap;
    }

    /**
     * create empty route
     *
     * @param context
     * @param RouteCompletionAction
     * @return
     * @throws Exception
     */
    public static Map createEmptyRoute(Context context, String RouteCompletionAction) throws Exception {
        //    System.out.println("templateId = " + templateId);

        if (UIUtil.isNullOrEmpty(RouteCompletionAction)) {
            RouteCompletionAction = "Promote Connected Object";
        }
        Map paramMap = new HashMap<String, Object>();
        String language = context.getLocale().getLanguage();
        paramMap.put("RouteCompletionAction", RouteCompletionAction);
//    paramMap.put("RouteCompletionAction", "Notify Route Owner");
        paramMap.put("Description", "");
        paramMap.put("languageStr", language);
        paramMap.put("portalMode", DomainConstants.EMPTY_STRING);
        paramMap.put("RouteBasePurpose", "Approval");
        paramMap.put("supplierOrgId", DomainConstants.EMPTY_STRING);
        paramMap.put("suiteKey", "Framework");
        paramMap.put("TemplateOID", null);
        paramMap.put("TemplateDisplay", DomainConstants.EMPTY_STRING);
        paramMap.put("VisbleToParent", DomainConstants.EMPTY_STRING);
        paramMap.put("AutoStopOnRejection", "Immediate");

        paramMap.put("Name", DomainConstants.EMPTY_STRING);
        paramMap.put("autoNameCheck", "true");
        paramMap.put("AutoNameSeries", DomainConstants.EMPTY_STRING);
        paramMap.put("Vault", DomainConstants.EMPTY_STRING);
        paramMap.put("Revision", DomainConstants.EMPTY_STRING);
        paramMap.put("selscope", "Organization");
        paramMap.put("folderId", DomainConstants.EMPTY_STRING);
        paramMap.put("txtWSFolder", "\u9009\u62e9\u4f5c\u7528\u8303\u56f4");

//        System.out.println("paramMap = " + paramMap);

        String[] args = JPO.packArgs(paramMap);
        Map routeMap = (Map) JPO.invoke(context, "emxRoute", null, "createRouteProcess", args, Map.class);
//        System.out.println("routeMap = " + routeMap);
        return routeMap;
    }


    /**
     * create empty route
     *
     * @param context
     * @param attrMap 指定创建时的属性
     * @return
     * @throws Exception
     */
    public static Map createRoute(Context context, Map attrMap) throws Exception {
        //    System.out.println("templateId = " + templateId);
        Map paramMap = new HashMap<String, Object>();
        String language = context.getLocale().getLanguage();
        paramMap.put("RouteCompletionAction", null);
//    paramMap.put("RouteCompletionAction", "Notify Route Owner");
        paramMap.put("Description", "");
        paramMap.put("languageStr", language);
        paramMap.put("portalMode", DomainConstants.EMPTY_STRING);
        paramMap.put("RouteBasePurpose", "Approval");
        paramMap.put("supplierOrgId", DomainConstants.EMPTY_STRING);
        paramMap.put("suiteKey", "Framework");
        paramMap.put("TemplateOID", null);
        paramMap.put("TemplateDisplay", DomainConstants.EMPTY_STRING);
        paramMap.put("VisbleToParent", DomainConstants.EMPTY_STRING);
        paramMap.put("AutoStopOnRejection", "Immediate");

        paramMap.put("Name", DomainConstants.EMPTY_STRING);
        paramMap.put("autoNameCheck", "true");
        paramMap.put("AutoNameSeries", DomainConstants.EMPTY_STRING);
        paramMap.put("Vault", DomainConstants.EMPTY_STRING);
        paramMap.put("Revision", DomainConstants.EMPTY_STRING);
        paramMap.put("selscope", "Organization");
        paramMap.put("folderId", DomainConstants.EMPTY_STRING);
        paramMap.put("txtWSFolder", "\u9009\u62e9\u4f5c\u7528\u8303\u56f4");

        paramMap.putAll(attrMap);
//        System.out.println("paramMap = " + paramMap);
        String[] args = JPO.packArgs(paramMap);
        Map routeMap = (Map) JPO.invoke(context, "emxRoute", null, "createRouteProcess", args, Map.class);
//        System.out.println("routeMap = " + routeMap);
        return routeMap;
    }

    /**
     * 通过流程模板创建流程
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static Map createRouteByRouteTemplate(Context context, String TemplateOID) throws Exception {
        //    System.out.println("templateId = " + templateId);
        Map paramMap = new HashMap<String, Object>();
        String language = context.getLocale().getLanguage();
        paramMap.put("RouteCompletionAction", "Promote Connected Object");
//    paramMap.put("RouteCompletionAction", "Notify Route Owner");
        paramMap.put("Description", "");
        paramMap.put("languageStr", language);
        paramMap.put("portalMode", DomainConstants.EMPTY_STRING);
        paramMap.put("RouteBasePurpose", "Approval");
        paramMap.put("supplierOrgId", DomainConstants.EMPTY_STRING);
        paramMap.put("suiteKey", "Framework");
        paramMap.put("TemplateOID", TemplateOID);
        paramMap.put("TemplateDisplay", DomainConstants.EMPTY_STRING);
        paramMap.put("VisbleToParent", DomainConstants.EMPTY_STRING);
        paramMap.put("AutoStopOnRejection", "Immediate");

        paramMap.put("Name", DomainConstants.EMPTY_STRING);
        paramMap.put("autoNameCheck", "true");
        paramMap.put("AutoNameSeries", DomainConstants.EMPTY_STRING);
        paramMap.put("Vault", DomainConstants.EMPTY_STRING);
        paramMap.put("Revision", DomainConstants.EMPTY_STRING);
        paramMap.put("selscope", "Organization");
        paramMap.put("folderId", DomainConstants.EMPTY_STRING);
        paramMap.put("txtWSFolder", "\u9009\u62e9\u4f5c\u7528\u8303\u56f4");
//        System.out.println("paramMap = " + paramMap);
        String[] args = JPO.packArgs(paramMap);
        Map routeMap = (Map) JPO.invoke(context, "emxRoute", null, "createRouteProcess", args, Map.class);
//        System.out.println("routeMap = " + routeMap);
        return routeMap;
    }


    /**
     * route add node
     *
     * @param context
     * @param nodesMap
     * @param route
     * @throws Exception
     */
    public static void addNode(Context context, Map<Integer, MapList> nodesMap, Route route) throws Exception {
//        nodesMap = {1=[{person=2016, title=title}], 2=[{person=2016, title=title2}], 3=[{person=2018, title=title3}], 4=[{person=2018 , title=title4}, {person= admin_platform, title=title4}], 5=[{person=admin_platform, title=5 6=[{person=2018, title=title6}]}
        //
        // nodeMap  key   task
        Set<Integer> set = nodesMap.keySet();
        TreeSet<Integer> sequenceSet = new TreeSet(set);
        Iterator<Integer> it = sequenceSet.iterator();
        int count = 1;
        while (it.hasNext()) {
            Integer sequence = it.next();
            MapList nodeList = nodesMap.get(sequence);
            boolean ruleflag = false;
            if (nodeList.size() > 1) {
                ruleflag = true;
            }
            for (int i = 0; i < nodeList.size(); i++) {
                Map nodeMap_i = (Map) nodeList.get(i);
                String person_i = "";
                if (nodeMap_i.containsKey("person")) {
                    person_i = (String) nodeMap_i.get("person");
                } else {
                    person_i = (String) nodeMap_i.get(DomainConstants.SELECT_NAME);
                }
//                System.out.println("person_i = " + person_i);
                String title_i = (String) nodeMap_i.get("title");
                String personObjectID = PersonUtil.getPersonObjectID(context, person_i);
//                System.out.println("personObjectID = "+personObjectID);
                DomainRelationship connect = DomainRelationship.connect(context, route, Constants.rel_RouteNode, DomainObject.newInstance(context, personObjectID));
                connect.setAttributeValue(context, Constants.attr_RouteSequence, String.valueOf(count));
                connect.setAttributeValue(context, Constants.attr_DueDateOffset, String.valueOf(count));
                connect.setAttributeValue(context, Constants.attr_Title, title_i);
                connect.setAttributeValue(context, Constants.attr_RouteAction, Constants.val_approve);
                connect.setAttributeValue(context, Constants.attr_RouteInstructions, String.valueOf(count));
                connect.setAttributeValue(context, Constants.attr_DateOffsetFrom, Constants.val_RouteStartDate);
                if (ruleflag) {
                    connect.setAttributeValue(context, Constants.attr_ParallelNodeProcessionRule, Constants.val_All);
                }
            }
            count++;
        }
//        System.out.println();
    }


    /**
     * route add content
     *
     * @param context
     * @param route
     * @throws FrameworkException
     */
    public static void addRouteContent(Context context, Route route, String[] selObjects) throws Exception {
        StringList selectTypeStmts = new StringList();
        selectTypeStmts.add(route.SELECT_NAME);
        DomainObject docObj = DomainObject.newInstance(context);
        MapList contentList = new MapList();
        StringList selects = new StringList();
        selects.add(DomainConstants.SELECT_ID);
        selects.add(DomainConstants.SELECT_CURRENT);
        selects.add(DomainConstants.SELECT_NAME);
        selects.add(DomainConstants.SELECT_POLICY);
        for (int i = 0; i < selObjects.length; i++) {
            docObj.setId(selObjects[i]);
            Map objMap = docObj.getInfo(context, selects);
            contentList.add(objMap);
        }
        route.AddContent(context, contentList);

        updateRouteRelAttr(context, route);

    }


    /**
     * 更新流程和关联对象的关系属性值
     *
     * @param context
     * @param route
     * @throws Exception
     */
    public static void updateRouteRelAttr(Context context, Route route) throws Exception {
        StringList busList = new StringList();
        busList.add(DomainConstants.SELECT_ID);
        busList.add(DomainConstants.SELECT_POLICY);
        busList.add(DomainConstants.SELECT_CURRENT);
        StringList relList = new StringList();
        relList.add(DomainConstants.SELECT_RELATIONSHIP_ID);
        MapList relatedObjects = route.getRelatedObjects(context, Constants.rel_ObjectRoute, "*", busList, relList, true, false, (short) 1, null, null);

        //使用超级管理员 更改属性设置 防止权限
        ContextUtil.pushContext(context);
        for (int i = 0; i < relatedObjects.size(); i++) {
            Map map_i = (Map) relatedObjects.get(i);
            String policy_i = (String) map_i.get(DomainConstants.SELECT_POLICY);
            String relId_i = (String) map_i.get(DomainConstants.SELECT_RELATIONSHIP_ID);
            String current_i = (String) map_i.get(DomainConstants.SELECT_CURRENT);
            String rel_policy = FrameworkUtil.getAliasForAdmin(context, "Policy", policy_i, true);
            String rel_state = FrameworkUtil.reverseLookupStateName(context, policy_i, current_i);

            DomainRelationship relationship = DomainRelationship.newInstance(context, relId_i);
            relationship.setAttributeValue(context, DomainConstants.ATTRIBUTE_ROUTE_BASE_POLICY, rel_policy);
            relationship.setAttributeValue(context, DomainConstants.ATTRIBUTE_ROUTE_BASE_STATE, rel_state);
            relationship.setAttributeValue(context, DomainConstants.ATTRIBUTE_ROUTE_BASE_PURPOSE, "Approval");
        }
        ContextUtil.popContext(context);

    }


    /**
     * @param context
     * @param domainObject
     * @throws FrameworkException
     */
    public static MapList getObjectRoute(Context context, DomainObject domainObject) throws Exception {
//        return domainObject.getRelatedObjects(context, Constants.rel_ObjectRoute, Constants.type_Route, HConstants.basicList, HConstants.relList, false, true, (short) 1, null, null);
        return HDomainObject.getRelatedObjectsAttr(context, domainObject, Constants.type_Route, Constants.rel_ObjectRoute, HConstants.basicList, HConstants.relList, false, true, (short) 1);

    }


    /**
     * @param context
     * @param args
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/20
     * @Description: 导出流程模板信息
     */
    public void routeTemplateExport(Context context, String[] args) {

        _logger.info(" --------------------------- routeTemplateExport --------------------------- ");
        boolean popflag = false;
        try {
            if (args.length < 1) {
                _logger.warning("args[] param is empty \n args[0] is out file path");
                return;
            }

            ContextUtil.pushContext(context);

            StringList busList = new StringList();
            busList.add(DomainObject.SELECT_ID);
            busList.add(DomainObject.SELECT_TYPE);
            busList.add(DomainObject.SELECT_NAME);
            busList.add(DomainObject.SELECT_REVISION);
            busList.add(DomainObject.SELECT_DESCRIPTION);
            busList.add(DomainObject.SELECT_CURRENT);
            busList.add(DomainObject.SELECT_OWNER);//所有者
            busList.add(DomainObject.SELECT_ORGANIZATION); //合作区
            busList.add(DomainObject.SELECT_PROJECT);//组织

            String typeAttr = MqlUtil.mqlCommand(context, "print type $1 select attribute $2 $3", TYPE_ROUTE_TEMPLATE, "dump", "|");
            if (UIUtil.isNotNullAndNotEmpty(typeAttr)) {
                String[] taSplit = typeAttr.split("\\|");
                for (String attr : taSplit) {
                    busList.add("attribute[" + attr + "]");
                }
            }

            StringList relList = new StringList();
            String relAttr = MqlUtil.mqlCommand(context, "print relationship $1 select attribute $2 $3", RELATIONSHIP_ROUTENODE, "dump", "|");
            if (UIUtil.isNotNullAndNotEmpty(relAttr)) {
                String[] raSplit = relAttr.split("\\|");
                for (String attr : raSplit) {
                    if (attr.equals("Route Node ID")) {
                        continue;
                    }
                    relList.add("attribute[" + attr + "]");
                }
            }


            //流程模板数据
            MapList rtMapList = DomainObject.findObjects(context, TYPE_ROUTE_TEMPLATE, "*", "", busList);
            _logger.info("rtMapList.size() : " + rtMapList.size());

            JSONArray dataArray = new JSONArray();
            for (int i = 0; i < rtMapList.size(); i++) {
                if (i % 10 == 0 || i == rtMapList.size() - 1) {
                    _logger.info("export i : " + i);
                }
                Map map_i = (Map) rtMapList.get(i);
                JSONObject rtJson_i = getRouteTemplateJson(context, map_i, busList, relList);
                dataArray.put(rtJson_i);
            }

            //创建文件夹
            String outPath = args[0];
            _logger.info("outPath : " + outPath);

            File outFile = new File(outPath);
            File parentFile = outFile.getParentFile();
            if (!parentFile.exists() || !parentFile.isDirectory()) {
                parentFile.mkdirs();
            }

            //输出到文件
            writer(outPath, dataArray.toString());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (popflag) {
                try {
                    ContextUtil.popContext(context);
                } catch (FrameworkException e) {
                    e.printStackTrace();
                }
            }

        }
        _logger.info(" --------------------------- routeTemplateExport --------------------------- ");
    }


    /**
     * @param context
     * @param args
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/20
     * @Description: 导出流程模板信息
     */
    public void routeTemplateImport(Context context, String[] args) {

        _logger.info(" --------------------------- routeTemplateImport --------------------------- ");
        boolean popflag = false;
        try {
            if (args.length < 1) {
                _logger.warning("args[] param is empty \n args[0] is import file path");
                return;
            }

            ContextUtil.pushContext(context);
            MqlUtil.mqlCommand(context, "trigger off");

            String filePath = args[0];
            _logger.info("filePath : " + filePath);

            String rtStr = getFileData(filePath);
            _logger.info("rtStr.length() : " + rtStr.length());

            JSONArray rtArray = new JSONArray(rtStr);
            _logger.info("rtArray.length() : " + rtArray.length());

            StringList busList = new StringList();
            busList.add(DomainObject.SELECT_ID);
            busList.add(DomainObject.SELECT_TYPE);
            busList.add(DomainObject.SELECT_NAME);
            busList.add(DomainObject.SELECT_REVISION);
            busList.add(DomainObject.SELECT_DESCRIPTION);
            busList.add(DomainObject.SELECT_CURRENT);
            busList.add(DomainObject.SELECT_OWNER);//所有者
            busList.add(DomainObject.SELECT_ORGANIZATION); //合作区
            busList.add(DomainObject.SELECT_PROJECT);//组织

            String typeAttr = MqlUtil.mqlCommand(context, "print type $1 select attribute $2 $3", TYPE_ROUTE_TEMPLATE, "dump", "|");
            if (UIUtil.isNotNullAndNotEmpty(typeAttr)) {
                String[] taSplit = typeAttr.split("\\|");
                for (String attr : taSplit) {
                    busList.add("attribute[" + attr + "]");
                }
            }

            StringList relList = new StringList();
            String relAttr = MqlUtil.mqlCommand(context, "print relationship $1 select attribute $2 $3", RELATIONSHIP_ROUTENODE, "dump", "|");
            if (UIUtil.isNotNullAndNotEmpty(relAttr)) {
                String[] raSplit = relAttr.split("\\|");
                for (String attr : raSplit) {
                    relList.add("attribute[" + attr + "]");
                }
            }


            //名称版本重复的 跳过
            JSONArray skipArray = new JSONArray();

            for (int i = 0; i < rtArray.length(); i++) {
                JSONObject json_i = rtArray.getJSONObject(i);
                _logger.info("import json_i : " + i + "    " + json_i);

                //创建流程模板
                creatRouteTemplate(context, json_i, skipArray, busList, relList);
            }

            //修改流程模板序列号
            modNumberGenerator(context, rtArray, busList);


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (popflag) {
                try {
                    ContextUtil.popContext(context);
                } catch (FrameworkException e) {
                    e.printStackTrace();
                }
            }
            try {
                MqlUtil.mqlCommand(context, "trigger on");
            } catch (FrameworkException e) {
                e.printStackTrace();
            }

        }
        _logger.info(" --------------------------- routeTemplateImport --------------------------- ");
    }

    /**
     * @param context
     * @param rtArray
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/21
     * @Description:
     */
    private void modNumberGenerator(Context context, JSONArray rtArray, StringList busList) throws FrameworkException {
        String smaxNum = "-1";
        //找到最大的数字
        for (int i = 0; i < rtArray.length(); i++) {
            JSONObject json_i = rtArray.getJSONObject(0);
            String name_i = json_i.getString(DomainConstants.SELECT_NAME);
            if (name_i.contains("-") && name_i.lastIndexOf("-") < name_i.length() - 1) {
                String snMum_i = name_i.substring(name_i.lastIndexOf("-") + 1);
                if (isNumeric(snMum_i) && Integer.parseInt(snMum_i) > Integer.parseInt(smaxNum)) {
                    smaxNum = snMum_i;
                }
            }
        }

        _logger.info("smaxNum : " + smaxNum);

        if (!smaxNum.equals("-1")) {
            //找到计数器
            StringList whereList = new StringList();
            whereList.add("name==\"" + "TYPE_ROUTE_TEMPLATE" + "\"");
            whereList.add("revision==\"" + "1" + "\"");
            String whereStr = whereList.join("&&");

            MapList rtnList = DomainObject.findObjects(context, TYPE_ROUTE_TEMPLATE, "*", whereStr, busList);
            _logger.info("rtnList.size() : " + rtnList.size());

            if (!rtnList.isEmpty()) {
                Map map0 = (Map) rtnList.get(0);
                String rtnId = (String) map0.get(DomainConstants.SELECT_ID);
                DomainObject rtnObj = DomainObject.newInstance(context, rtnId);
                String nextNumber = rtnObj.getAttributeValue(context, ATTRIBUTE_ESERVICE_NEXT_NUMBER);
                _logger.info("nextNumber : " + nextNumber);

                int iSmaxNum = Integer.parseInt(smaxNum);
                if (iSmaxNum > Integer.parseInt(nextNumber)) {
                    String.format("%0" + nextNumber.length() + "d", iSmaxNum + 1);
                    rtnObj.setAttributeValue(context, ATTRIBUTE_ESERVICE_NEXT_NUMBER, smaxNum);
                }
            }
        }
    }

    /**
     * @param str
     * @return boolean
     * @Author HLY
     * @CreateTime 2023/11/21
     * @Description:
     */
    public boolean isNumeric(String str) {
        return str.matches("-?\\d+(\\.\\d+)?");
    }


    /**
     * @param context
     * @param json
     * @param skipArray
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/21
     * @Description: 创建流程模板
     */
    private void creatRouteTemplate(Context context, JSONObject json, JSONArray skipArray, StringList busList, StringList relList) throws MatrixException {
        String name = json.getString(DomainConstants.SELECT_NAME);
        String revision = json.getString(DomainConstants.SELECT_REVISION);
        String owner = json.getString(DomainConstants.SELECT_OWNER);
        String organization = json.getString(DomainConstants.SELECT_ORGANIZATION);//合作区
        String project = json.getString(DomainConstants.SELECT_PROJECT);//组织
        String current = json.getString(DomainConstants.SELECT_CURRENT);
        String description = json.getString(DomainConstants.SELECT_DESCRIPTION);


        StringList whereList = new StringList();
        whereList.add("name==\"" + name + "\"");
        whereList.add("revision==\"" + revision + "\"");
        String whereStr = whereList.join("&&");

        MapList rtList = DomainObject.findObjects(context, TYPE_ROUTE_TEMPLATE, "*", whereStr, busList);
        _logger.info("creatRouteTemplate rtList.size() : " + rtList.size());

        if (rtList.isEmpty()) {

            BusinessObject rtBusObj = new BusinessObject(TYPE_ROUTE_TEMPLATE, name, revision, ProgramCentralConstants.VAULT_eSERVICE_PRODUCTION);
            rtBusObj.create(context, POLICY_ROUTE_TEMPLATE);
            _logger.info("rtBusObj : " + rtBusObj);

            DomainObject rtObj = DomainObject.newInstance(context, rtBusObj);
            _logger.info("rtObj : " + rtObj);

            //获取要设置的属性
            Map attrMap = new HashMap();
            for (int i = 0; i < busList.size(); i++) {
                String attr_i = busList.get(i);
                if (attr_i.startsWith("attribute[") && attr_i.endsWith("]") && json.has(attr_i)) {
                    String mAttr_i = attr_i.substring("attribute[".length(), attr_i.length() - 1);
                    attrMap.put(mAttr_i, json.getString(attr_i));
                }
            }
            _logger.info("attrMap : " + attrMap);

            //设置属性
            rtObj.setAttributeValues(context, attrMap);
            _logger.info("rtObj.setAttributeValues(context, attrMap) : ");

//            //设置所有者
//            rtObj.setOwner(context, owner);
//            _logger.info("rtObj.setOwner(context, owner) : ");

            String createId = rtObj.getInfo(context, DomainConstants.SELECT_ID);
            _logger.info("createId : " + createId);

            //设置合作区 组织 当前状态
            MqlUtil.mqlCommand(context, "mod bus $1 project $2 organization $3 current $4 owner $5 description $6", createId, project, organization, current, owner, description);

            String ownerId = PersonUtil.getPersonObjectID(context, owner);
            _logger.info("ownerId : " + ownerId);

            //建立和所有者的关系
            DomainRelationship connect = DomainRelationship.connect(context, DomainObject.newInstance(context, ownerId), RELATIONSHIP_ROUTE_TEMPLATES, rtObj);
            String relPhyId = connect.getPhysicalId(context);
            MqlUtil.mqlCommand(context, "mod connection $1 owner $2", relPhyId, owner);

            //添加节点
            JSONArray nodesArray = json.getJSONArray("nodes");
            if (!nodesArray.isEmpty()) {
                addRouteTemplateNode(context, nodesArray, rtObj, owner, relList);
            }

        } else {
            skipArray.put(json);
        }
    }


    /**
     * @param context
     * @param nodesArray
     * @param rtObj
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/21
     * @Description:
     */
    private void addRouteTemplateNode(Context context, JSONArray nodesArray, DomainObject rtObj, String routOwner, StringList relList) throws MatrixException {
        _logger.info(" --------------------------- addRouteTemplateNode --------------------------- ");

        for (int i = 0; i < nodesArray.length(); i++) {
            JSONObject nodeJson_i = nodesArray.getJSONObject(i);
            _logger.info("nodeJson_i : " + nodeJson_i);
            String name_i = nodeJson_i.getString(DomainConstants.SELECT_NAME);
            String personId_i = PersonUtil.getPersonObjectID(context, name_i);
            DomainRelationship conn_i = DomainRelationship.connect(context, rtObj, RELATIONSHIP_ROUTENODE, DomainObject.newInstance(context, personId_i));
            Map rtRelAttrMap_i = getRtRelAttrMap(nodeJson_i, relList);
            String relPhyId_i = conn_i.getPhysicalId(context);
            rtRelAttrMap_i.put("Route Node ID", relPhyId_i);
            conn_i.setAttributeValues(context, rtRelAttrMap_i);
            MqlUtil.mqlCommand(context, "mod connection $1 owner $2", relPhyId_i, routOwner);

        }
        _logger.info(" --------------------------- addRouteTemplateNode --------------------------- ");
    }

    /**
     * @param json
     * @return Map
     * @Author HLY
     * @CreateTime 2023/11/21
     * @Description:
     */
    private Map getRtRelAttrMap(JSONObject json, StringList relList) {
        //获取要设置的属性
        Map attrMap = new HashMap();
        for (int i = 0; i < relList.size(); i++) {
            String attr_i = relList.get(i);
            if (attr_i.startsWith("attribute[") && attr_i.endsWith("]") && json.has(attr_i)) {
                String mAttr_i = attr_i.substring("attribute[".length(), attr_i.length() - 1);
                attrMap.put(mAttr_i, json.getString(attr_i));
            }
        }
//        _logger.info("attrMap : " + attrMap);
        return attrMap;
    }

    /**
     * @param context
     * @param rtMap
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/21
     * @Description:
     */
    private JSONObject getRouteTemplateJson(Context context, Map rtMap, StringList busList, StringList relList) throws FrameworkException {

        String rtId = (String) rtMap.get(DomainConstants.SELECT_ID);//流程模板id

        DomainObject rtObj = DomainObject.newInstance(context, rtId);//流程模板对象

        Map rtInfo = rtObj.getInfo(context, busList);//流程模板信息

        JSONObject rtJson = new JSONObject(rtInfo);

        //流程模板节点信息
        MapList nodeList = rtObj.getRelatedObjects(context, DomainConstants.RELATIONSHIP_ROUTE_NODE, DomainConstants.TYPE_PERSON, busList, relList, false, true, (short) 1, null, null, 0);

        JSONArray nodeArray = new JSONArray(nodeList);

        rtJson.put("nodes", nodeArray);

        return rtJson;

    }


    /**
     * @param path    文件路径
     * @param content 要输出内容
     * @return void
     * @Author HLY
     * @CreateTime 2023/9/28
     * @Description:把文本内容写入到文件
     */
    private void writer(String path, String content) throws IOException {
        FileOutputStream fout = null;
        FileChannel channel = null;
        try {
            byte[] arr = content.getBytes("utf-8");
            fout = new FileOutputStream(path);//
            channel = fout.getChannel();//
            ByteBuffer buffer = ByteBuffer.allocate(arr.length);//
            buffer.put(arr);
            buffer.flip();
            channel.write(buffer);//
            buffer.clear();//
        } finally {
            if (fout != null) {
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 读取文件中的数据
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static String getFileData(String filePath) throws Exception {
        String line = "";
        BufferedReader br = null;
        List<String> dataList = new ArrayList<String>();
        try {
            br = new BufferedReader(new FileReader(filePath));
            while ((line = br.readLine()) != null) {
                dataList.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                br.close();
            }
        }
        if (!dataList.isEmpty()) {
            StringList dList = new StringList(dataList);
            return dList.join("");
        }
        return DomainConstants.EMPTY_STRING;
    }
}
